/*
 * Licensed to the 南京汇海交通科技有限公司
 *
 * Copyright (c) 2025.
 * All rights reserved.
 *
 * 本软件属南京汇海交通科技有限公司所有，在未获得南京汇海交通科技有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.chframework.json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import org.apache.commons.lang3.StringUtils;

import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

/**
 * <p>
 * 以JsonPath解析json字符串
 * </p>
 *
 * @author 周孝兵
 * @since 2021-12-10
 */
public final class JsonParser {

    private TreeMap<String, Object> pathValueMap;

    public JsonParser(String json) {
        this.pathValueMap = new TreeMap<>();
        this.setPathValueMap(json);
    }

    /**
     * 获取所有节点的jsonPath和value
     */
    public Map<String, Object> getPathValueMap() {
        return this.pathValueMap;
    }

    /**
     * 处理json报文
     */
    private void setPathValueMap(String json) {
        try {
            JsonMapper jsonMapper = new JsonMapper();
            JsonNode jsonNode = jsonMapper.readTree(json);
            String jsonPath = "$";
            if (StringUtils.isNotBlank(json)) {
                this.recursion(jsonNode, jsonPath);
            }
        } catch (JsonProcessingException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 读取对象节点
     */
    private void readObject(JsonNode objectNode, String jsonPath) {
        String parentPath = jsonPath;
        Iterator<Map.Entry<String, JsonNode>> nodeIter = objectNode.fields();
        while (nodeIter.hasNext()) {
            Map.Entry<String, JsonNode> field = nodeIter.next();
            String key = field.getKey();
            JsonNode childNode = field.getValue();

            jsonPath = parentPath + "." + key;
            this.recursion(childNode, jsonPath);
        }
    }

    /**
     * 读取数组节点
     */
    private void readArray(JsonNode arrayNode, String jsonPath) {
        String parentPath = jsonPath;
        for (int i = 0; i < arrayNode.size(); i++) {
            JsonNode elementNode = arrayNode.get(i);
            jsonPath = parentPath + "[" + i + "]";

            this.recursion(elementNode, jsonPath);
        }
    }

    /**
     * 判断节点类型，进行不同的读取方式
     */
    private void recursion(JsonNode node, String jsonPath) {
        if (node.getNodeType() == JsonNodeType.ARRAY) {
            this.readArray(node, jsonPath);
        } else if (node.getNodeType() == JsonNodeType.OBJECT) {
            this.readObject(node, jsonPath);
        } else {
            this.pathValueMap.put(jsonPath, node.getNodeType() == JsonNodeType.NULL ? null : node.asText());
        }
    }

}
